package cn.wolfcode.ssm.shiro;

import cn.wolfcode.ssm.domain.Employee;
import cn.wolfcode.ssm.domain.Role;
import cn.wolfcode.ssm.mapper.EmployeeMapper;
import cn.wolfcode.ssm.mapper.PermissionMapper;
import cn.wolfcode.ssm.mapper.RoleMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("CrmRealm")
public class CrmRealm extends AuthorizingRealm {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;



    @Autowired
    @Override
    // 这里是注入凭证匹配器 ,不然登陆的时候不会把密码加密
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }

    @Override
    // 认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 用户登陆时候获取用户名
        Object username = token.getPrincipal();

        // 通过用户穿上来的username判断数据坤中有没有这个对象
        Employee employee = employeeMapper.checkName((String)username);


        // 如果这个对象不为空
        if (employee != null){
            // 拿到用户先判断账户是否被冻结
            if (employee.isStatus() == false){

                throw new  DisabledAccountException();
            }
            // 如果登录对象,密码都正确.第三个自己加的盐(你的盐是什么byte后面就是填什么),自定义的realm的名字
         return new SimpleAuthenticationInfo(employee,
                 employee.getPassword(),
                 ByteSource.Util.bytes(employee.getName()),
                 "CrmRealm");
        }
        // 不存在这个对象就返回null;
        return null;
    }

    @Override
    // 授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 通过shiro拿到登陆对象
        Employee employee = (Employee) SecurityUtils.getSubject().getPrincipal();
        // 判断是不是超管
        if(employee.isAdmin()){
            info.addRole("ADMIN");
            //  "*:*"这是权限通配符,配置了这个,管理员才能访问所有的页面
            info.addStringPermission("*:*");
        }else{
            // 根据用户id拿到员工的角色集合
            // 这种方法拿到的是角色的集合,不是String类型的角色编码
            List<Role> roles = roleMapper.selectedByEmpId(employee.getId());
            ArrayList<String> roleSn = new ArrayList<String>();
            // 遍历角色的集合
            for (Role role : roles) {
                // 拿到角色里面的角色编码存到roleSn集合中
                roleSn.add(role.getSn());
            }
            // 最后把集合存起来
            info.addRoles(roleSn);
            // 根据用户id拿到员工的权限集合
            List<String> permissions = permissionMapper.selectedByEmpId(employee.getId());
            // 存到info中
            info.addStringPermissions(permissions);
        }
        return info;
    }


}
